package com.ruoyi.client.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.client.exception.JeepayException;
import com.ruoyi.client.response.PayResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

/**
 * Jeepay工具类
 */
@Slf4j
public class JeepayKit {

    /**
     * 获取签名串
     * @param map
     * @return  urlParam.append(key).append("=").append( paraMap.get(key) == null ? "" : paraMap.get(key) );
     */
    public static String getStrSort(Map<String,Object> map){
        ArrayList<String> list = new ArrayList<String>();
        for(Map.Entry<String,Object> entry:map.entrySet()){
            if(null != entry.getValue() && !"".equals(entry.getValue())){
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        return sb.toString();
    }

    /**
     * 获取当前系统时间戳
     * @return 时间戳字符串
     */
    public static String getTimestamp() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    /**
     * 将对象转换为JSON字符串
     * @param object 对象
     * @return JSON字符串
     */
    public static String toJsonString(Object object) {
        return JSON.toJSONString(object);
    }

    /**
     * 将JSON字符串转换为对象
     * @param json JSON字符串
     * @param clazz 目标对象类型
     * @param <T> 目标对象泛型
     * @return 目标对象实例
     */
    public static <T> T parseObject(String json, Class<T> clazz) {
        return JSON.parseObject(json, clazz);
    }

    /**
     * 发送HTTP POST请求
     * @param url 请求URL
     * @param params 请求参数
     * @return 响应内容
     * @throws IOException IO异常
     */
    public static String doPost(String url, Map<String, Object> params) throws IOException {
        String reqBody = JSON.toJSONString(params);
        log.debug("请求URL: {}, 请求参数: {}", url, reqBody);

        HttpURLConnection conn = null;
        BufferedReader reader = null;
        try {
            URL requestUrl = new URL(url);
            conn = (HttpURLConnection) requestUrl.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            conn.setRequestProperty("Accept", "application/json");
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.connect();

            try (OutputStream os = conn.getOutputStream()) {
                os.write(reqBody.getBytes(StandardCharsets.UTF_8));
                os.flush();
            }

            StringBuilder response = new StringBuilder();
            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }

            String respBody = response.toString();
            log.debug("响应内容: {}", respBody);
            return respBody;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error("关闭响应流出错", e);
                }
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    /**
     * 解析响应内容
     * @param respContent 响应内容
     * @param responseClass 响应类型
     * @param <T> 响应泛型
     * @return 响应对象
     * @throws JeepayException Jeepay异常
     */
    public static <T extends PayResponse> T parseResponse(String respContent, Class<T> responseClass) throws JeepayException {
        if (StringUtils.isEmpty(respContent)) {
            throw new JeepayException("响应为空");
        }

        try {
            JSONObject respJson = JSON.parseObject(respContent);
            T response = JSON.toJavaObject(respJson, responseClass);
            if (response == null) {
                throw new JeepayException("解析响应失败");
            }
            return response;
        } catch (Exception e) {
            throw new JeepayException("解析响应异常: " + e.getMessage(), e);
        }
    }
}
